<?php
require_once dirname(__FILE__) . '/../../bootstrap.unit.php';
require_once FORAGE_APP_PATH . '/behaviours/test/TestBehaviour.php';
require_once FORAGE_APP_PATH . '/behaviours/test/TestBehaviours.php';

class ForageResponseTest extends ForageUnitTestCase
{
  private $response;

  public function setUp()
  {
    $this->response = new ForageResponse();
  }

  public function tearDown()
  {
    unset($this->response);
  }

  public function getDocument()
  {
    return new ForageDocument('blah', 'blah');
  }

  public function testSettingTotal()
  {
    $this->assertNull($this->response->total, 'Total should initially be null');
    $this->response->setTotal(10);
    $this->assertEquals(10, $this->response->total, 'total should be set correctly');
  }

  public function testIteration()
  {
    $document = $this->getDocument();
    $this->response[] = $document;
    foreach ($this->response as $key => $doc) {
      $this->assertSame($document, $doc);
    }
  }

  public function testArrayAccess()
  {
    $document = $this->getDocument();
    $this->response[] = $document;
    $this->assertSame($document, $this->response[0]);
  }

  /**
   * @expectedException InvalidArgumentException
   */
  public function testSettingDocumentToPositionFails()
  {
    $document = $this->getDocument();
    $this->response[0] = $document;
  }

  /**
   * @expectedException InvalidArgumentException
   */
  public function testSettingNonDocumentFails()
  {
    $this->response[] = 'blah';
  }

  public function testArrayAccessImmutable()
  {
    try {
      unset($this->response[0]);
      $this->fail('response should be immutable');
    } catch (BadMethodCallException $e) {}
  }

  public function testAddingBehaviours()
  {
    $this->response->addBehaviour(new ForageTestResponseBehaviour());
    $this->assertTrue($this->response->behaviourTest());
  }

  /**
   * @expectedException BadMethodCallException
   */
  public function testBehaviourMethodFailsBeforeAdded()
  {
    $this->response->behaviourTest();
  }

  public function testCheckingForBehaviours()
  {
    $this->assertFalse($this->response->hasBehaviour('ForageTestResponseBehaviour'));
    $this->response->addBehaviour(new ForageTestResponseBehaviour());
    $this->assertTrue($this->response->hasBehaviour('ForageTestResponseBehaviour'));
  }

  /**
   * @expectedException InvalidArgumentException
   */
  public function testNonResponseBehaviourCannotBeAdded()
  {
    $this->response->addBehaviour(new ForageTestBehaviour());
  }
}
